昨天是說 Props 由父元件往下傳遞資料給子元件,今天來講 Emit event 有子元件往上傳遞資料給父元件。
Emit 是一個事件,相對於 Props 來說它不是即時的把資料往外傳送,也就是說它每次往外層送必須去觸發一個事件,它才會把資料往外層送,那該怎麼做?那就是自定義事件!
Events up
子元件要回應父元件的方式是 Event up
,就是 Vue 的事件處理,使用 v-on
接收事件觸發並且去呼叫對應的函式,這邊的事件我們可以自訂義,現在來看看該怎麼做。
Vue Instance 事件介面(Event Interface)實作方式包含以下兩種:
在模板裡是使用 v-on
綁定事件。
範例:
<div id="app">
<h2>透過 emit 向外傳遞資訊</h2>
我透過元件儲值了 {{ cash }} 元
<!-- increment 是自定義事件名稱 -->
<button-counter @increment="incrementTotal"></button-counter>
</div>
<script>
Vue.component('buttonCounter', {
template: `<div>
<button @click="incrementCounter">增加 {{ counter }} 元</button>
<input type="number" v-model="counter">
</div>`,
data: function() {
return {
counter: 1
}
},
methods: {
incrementCounter: function() {
// 觸發外層 increment 的事件
// emit 也可以傳遞參數
// 確保它傳入的是數值用 Number
this.$emit("increment", Number(this.counter));
}
}
});
var app = new Vue({
el: '#app',
data: {
cash: 300
},
methods: {
incrementTotal(newNum) {
this.cash += newNum;
}
}
});
</script>
有時候你會想要在元件上綁定原生事件,你可以加上 .native
修飾符號:
<dice-button @roll="showResult" @click.native="doWhat">
前面都是父子溝通,那兩個子元件要如何溝通?因為每個元件都是獨立運作在自己的範圍,所以我們可以透過一個空的 vue instance 作為中央事件總線。
// 創建空的Vue Instance "bus"
var bus = new Vue()
// 觸發A元件中的事件 "id-selected"
bus.$emit('id-selected', 1)
// 在B元件的 "created" 鉤子中監聽 "id-selected" 這個事件
bus.$on('id-selected', function(id) {
// content
})
此應用只適合小網站應用,如果有很多子元件都透過這樣的方式溝通,會讓這個bus管理線變得很繁忙複雜,所以中大型網站官方推薦使用Vuex,它是一個狀態管理模式。
Day17 - [Components] 元件組合與溝通
Vue.js (9.2) - 元件(Component)
vue】組件的使用(3)自定義事件$ on / $ emit